package com.atguigu.gmall.activity.listener;

import com.atguigu.gmall.activity.mapper.SeckillGoodsMapper;
import com.atguigu.gmall.activity.util.DateUtil;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.model.activity.SeckillGoods;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;
import java.util.List;

/**
 * @author: 李旭
 * @create: 2021-09-17 14:09
 *
 *    营销活动  监听器
 **/
@Component
public class ActivityListener {

    @Autowired
    private SeckillGoodsMapper seckillGoodsMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    //将DB中数据压入缓存
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(value = MqConst.QUEUE_TASK_1,durable = "true",autoDelete = "false"),
                    exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_TASK),
                    key = {MqConst.ROUTING_TASK_1}
            )
    })
    public void receiverDataToRedisMessage(Message message, Channel channel){
        try {
            //将DB中数据压入缓存 select * from seckill_goods where stock_count > 0
            QueryWrapper queryWrapper = new QueryWrapper<SeckillGoods>();
            //1:查询DB中秒杀商品
            //1.1:  当天的
            queryWrapper.eq("DATE_FORMAT(start_time,'%Y-%m-%d')",
                    DateUtil.formatDate(new Date()));
            //1.2:  有库存  greater e
            queryWrapper.gt("stock_count","0");
            //1.3:  审核通过的
            queryWrapper.eq("status","1");
            List<SeckillGoods> seckillGoodsList = seckillGoodsMapper.selectList(queryWrapper);
            //2:写到缓存中
            seckillGoodsList.forEach(seckillGoods -> {
            //2.1: 缓存中已经存在了的  表示继续秒杀  不用再压入一次了
            //Map h  = new HashMap  h.put(hk,hv)   h:常量  hk:skuId.toString  hv:SeckillGoods
                if(!redisTemplate.opsForHash().hasKey(RedisConst.SECKILL_GOODS,
                        seckillGoods.getSkuId().toString())){
                    //2.2：缓存五大数据类型： Hash类型（散列类型）  秒杀商品 商品中属性 剩余库存
                    redisTemplate.opsForHash().put(RedisConst.SECKILL_GOODS,seckillGoods.getSkuId().toString()
                     ,seckillGoods);
                     //2.3: 能解决超卖问题吗？不能解决 （重大待解决问题）
                    // 将秒杀商品压入缓存中的List类型
                    String[] ids = buildSkuIds(seckillGoods.getStockCount(),seckillGoods.getSkuId());
                    redisTemplate.opsForList().leftPushAll(RedisConst.SECKILL_STOCK_PREFIX
                                    + seckillGoods.getSkuId(), ids);
                    //TODO 2.4:状态位
                }
            });
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //组装成一个skuId的数组
    private String[] buildSkuIds(Integer stockCount, Long skuId) {
        String[] ids = new String[stockCount];
        for (Integer i = 0; i < stockCount; i++) {
            ids[i] = skuId.toString();
        }
        return ids;
    }
}
